package org.activequant.util.tools;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * The Number Counter class can be used to count events and numbers happening in
 * a running VM for submittal to a tool like RRD. Runs immediately in its own thread. 
 * 
 * History: - [28.02.2009] Created (Ulrich Staudinger)<br>
 * <br>
 * 
 * @author Ulrich Staudinger
 * 
 */
public class NumberCounter extends RunnableTask {

	private HashMap<String, List<Double>> theNumbers = new HashMap<String, List<Double>>();
	private HashMap<String, Integer> theEventsPerInterval = new HashMap<String, Integer>();
	private long theSubmitEventsIntervalLength = 1000L;
	
	public NumberCounter(long anIntervalLength)
	{
		theSubmitEventsIntervalLength = anIntervalLength;	
		Thread myThread = new Thread(this);
		myThread.start();
	}
	

	/**
	 * adds a number to the internal list of numbers and counts the events as well. 
	 * 
	 * @param anEvent an event identifier as a plain string, for example: "RuntimeForQuoteProcessing"
	 * @param aNumber a double number to be counted, for example seconds with microseconds: 0.00826
	 */
	public synchronized void submitNumber(String anEvent, Double aNumber) {
		if (!theNumbers.containsKey(anEvent)) {
			theNumbers.put(anEvent, new ArrayList<Double>());
			theEventsPerInterval.put(anEvent, 0);
		}
		theNumbers.get(anEvent).add(aNumber);
		theEventsPerInterval.put(anEvent, theEventsPerInterval.get(anEvent)+1);
	}

	/**
	 * called from the thread. Not to be ran directly. 
	 */
	public void run() {
		// schedule a submittal
	}

	@SuppressWarnings("unchecked")
	private void submit() {
		HashMap<String, List<Double>> myNumbers;
		HashMap<String, Integer> myEventsPerInterval;
		// cloning ...
		synchronized (theNumbers) {
			myNumbers = (HashMap<String, List<Double>>) theNumbers.clone();
			myEventsPerInterval = (HashMap<String, Integer>) theEventsPerInterval
					.clone();
			// sweep.
			theNumbers.clear();
			theEventsPerInterval.clear();
		}

	}
}
